#include <iostream>
#include <fstream>
#include <iomanip>

#include "Transaction.h"

using namespace std;

/*
*	Fields
*/
const float Transaction::SALES_TAX = 0.075f;

/*
*	Constructors
*/
Transaction::Transaction(char* filename, Inventory* inventory) {
	file.open(filename, ios::app | ios::out);

	if (!file.is_open()) throw(ERR__OPEN_FILE);

	this->inventory = inventory;

	transactionOpen = true;

	subtotal = 0;
	tax = 0;

	/*
	*	Throw errors for duplicates in inventory
	*/
	for (int i = 0; i < inventory->duplicates.getCount(); ++i) {
		file << "*** Duplicate " << inventory->duplicates.get(i) << " ***" << endl;
	} //for
	file << endl << endl;
} //Transaction

/*
*	Destructor
*/
Transaction::~Transaction() {
	file.close();
} //~Transaction

/*
*	Properties
*/
float Transaction::getTax()			{ return tax; }
float Transaction::getSubtotal()	{ return subtotal; }

/*
*	Methods
*/
void Transaction::addItem(int productNumber, int amount) {
	if(!transactionOpen)	throw(ERR__MOD_CLOSED_TRANSACTION);
	if(amount <= 0)			throw(ERR_INVALID_AMOUNT);
	
	Product* product = inventory->find(productNumber);
	
	/*
	*	Write product initial information
	*
	*		If item doesn't exist
	*
	*			*** Item (productNumber) not in inventory ***
	*
	*		It item does exist
	*
	*			(item description)		(amount) @ (price) (price*amount)
	*/

	if(!product) {
		int digits = 0;
		for (int i = productNumber; i; i/=10) ++digits;

		digits = 5 - digits;
		if (!productNumber) --digits;

		file << "*** Item ";
		while (digits--) file << '0';
		file << productNumber << " not in inventory ***" << endl;

		return;
	} //if
	else {
		//<description>		@ <price> <sub>
		file << fixed << setprecision(2);

		file
			<< product->getDescription()												//description
			<< "\t" << amount															//amount
			<< " @ " << fixed << product->getPrice() << setprecision(2)					//price
			<< " " << fixed << product->getPrice()*amount << setprecision(2) << " ";	//product subtotal
	} //else
	
	/*
	*	If the item is taxable, append TX to the product information line
	*/
	if(product->getIsTaxable())		file << "TX";
	file << endl;

	/*
	*	Add the product total (price*amount) to subtotal
	*/
	subtotal += product->getPrice()*amount;
	
	/*
	*	If the product is taxable, add product tax (price*amount*taxRate) to tax var
	*/
	if(product->getIsTaxable())
		tax += product->getPrice()*amount*SALES_TAX;
} //addItem

float Transaction::calculateTotal() {
	return getSubtotal() + getTax();
} //calculateTotal

void Transaction::endTransaction() {
	if(!transactionOpen)	throw(ERR__MOD_CLOSED_TRANSACTION);

	file << fixed << setprecision(2);
	file << "Subtotal  " << fixed << subtotal << setprecision(2) << endl;
	file << "Tax\t " << fixed << tax << setprecision(2) << endl << endl;
	file << "Total\t" << fixed << calculateTotal() << setprecision(2) << endl;
	file << "--------------------------------------------------------";
	file << "\n\n";

	transactionOpen = false;
} //endTransaction